<template>
  <a-modal
    :open="open"
    :title="title"
    @cancel="handleCancel"
    :footer="null"
    width="800px"
    class="task-log-modal"
    :maskClosable="false"
  >
    <div class="log-container">
      <div class="log-header">
        <div class="log-info">
          <span class="label">{{ $t('logs.modal.executeTime') }}：</span>
          <span class="value">{{ formatTime(log?.startTime) }}</span>
          <span class="label">{{ $t('logs.modal.duration') }}：</span>
          <span class="value">{{ formatDuration(log?.duration) }}</span>
          <span class="label">{{ $t('logs.modal.status') }}：</span>
          <a-tag :color="getStatusColor(log?.status)">
            {{ getStatusText(log?.status) }}
          </a-tag>
        </div>
        <div class="actions">
          <a-tooltip :title="$t('logs.modal.copyLog')">
            <a-button type="text" @click="copyLog">
              <template #icon><CopyOutlined /></template>
            </a-button>
          </a-tooltip>
          <a-tooltip :title="$t('logs.modal.refresh')">
            <a-button type="text" @click="refreshLog">
              <template #icon><ReloadOutlined /></template>
            </a-button>
          </a-tooltip>
        </div>
      </div>
      
      <div class="log-content" ref="logContentRef">
        <a-spin :spinning="loading">
          <pre v-if="log?.output" class="output-text">{{ log.output }}</pre>
          <div v-else class="no-output">{{ $t('logs.modal.noOutput') }}</div>
        </a-spin>
      </div>
    </div>
  </a-modal>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
import { useI18n } from 'vue-i18n'
import { message } from 'ant-design-vue'
import { CopyOutlined, ReloadOutlined } from '@ant-design/icons-vue'
import dayjs from 'dayjs'
import { taskAPI } from '@/api'
import type { TaskExecution } from '@/types/task'
import { useWebSocket, type LogEvent } from '@/services/websocket'

interface Props {
  open: boolean
  taskId?: string
  executionId?: string
}

const props = defineProps<Props>()
const emit = defineEmits<{
  (e: 'update:open', open: boolean): void
}>()

const { t } = useI18n()
const log = ref<TaskExecution | null>(null)
const loading = ref(false)
const logContentRef = ref<HTMLElement>()

// WebSocket相关
const { on, off } = useWebSocket()
const isRealTimeMode = ref(false) // 是否启用实时模式

const title = computed(() => {
  if (props.taskId && log.value) {
    const status = log.value.status === 'running' ? t('logs.modal.running') : 
                   log.value.status === 'success' ? t('logs.status.success') : 
                   log.value.status === 'error' ? t('logs.status.failed') : t('logs.status.unknown')
    return `${t('logs.modal.title')} - ${status}${isRealTimeMode.value ? ` (${t('logs.modal.realtime')})` : ''}`
  }
  return t('logs.modal.title')
})

// 格式化时间
const formatTime = (time?: string) => {
  if (!time) return '-'
  return dayjs(time).format('YYYY-MM-DD HH:mm:ss')
}

// 格式化持续时间
const formatDuration = (duration?: number) => {
  if (!duration) return '-'
  if (duration < 1000) return `${duration}${t('logs.duration.ms')}`
  return `${(duration / 1000).toFixed(2)}${t('logs.duration.seconds')}`
}

// 获取状态颜色
const getStatusColor = (status?: string) => {
  switch (status) {
    case 'success':
      return 'success'
    case 'error':
      return 'error'
    case 'running':
      return 'processing'
    default:
      return 'default'
  }
}

// 获取状态文本
const getStatusText = (status?: string) => {
  switch (status) {
    case 'success':
      return t('logs.status.success')
    case 'error':
      return t('logs.status.failed')
    case 'running':
      return t('logs.status.running')
    default:
      return t('logs.status.unknown')
  }
}

// 复制日志内容
const copyLog = async () => {
  if (!log.value?.output) {
    message.warning(t('logs.modal.copyWarning'))
    return
  }
  
  try {
    await navigator.clipboard.writeText(log.value.output)
    message.success(t('logs.modal.copySuccess'))
  } catch (err) {
    message.error(t('logs.modal.copyFailed'))
  }
}

// 刷新日志
const refreshLog = () => {
  if (props.executionId) {
    loadLog()
  }
}

// 加载日志
const loadLog = async () => {
  if (!props.executionId) {
    log.value = null
    return
  }
  
  loading.value = true
  try {
    const data = await taskAPI.getExecution(props.executionId)
    log.value = data
    
    // 如果任务正在运行，启用实时模式
    if (data.status === 'running') {
      isRealTimeMode.value = true
    }
    
    console.log('[TaskLogModal] 加载日志成功:', data)
  } catch (error) {
    console.error('[TaskLogModal] 加载日志失败:', error)
    message.error(t('logs.modal.loadFailed'))
    log.value = null
  } finally {
    loading.value = false
  }
}

// 监听props变化
watch(
  () => props.executionId,
  () => {
    if (props.executionId) {
      loadLog()
    } else {
      log.value = null
    }
  },
  { immediate: true }
)

// 关闭窗口
const handleCancel = () => {
  emit('update:open', false)
}

// WebSocket事件处理
const handleLogEvent = (eventData: any) => {
  console.log('[TaskLogModal] 收到WebSocket日志事件:', eventData)
  
  // 后端发送的数据格式是 { log: LogEvent, time: timestamp }
  const event: LogEvent = eventData.log
  
  if (!event) {
    console.warn('[TaskLogModal] WebSocket事件数据格式错误:', eventData)
    return
  }
  
  // 只处理当前执行的日志
  if (event.executionId !== props.executionId) {
    console.log('[TaskLogModal] 忽略其他任务的日志事件:', event.executionId, 'vs', props.executionId)
    return
  }
  
  if (!log.value) {
    console.warn('[TaskLogModal] log.value为空，无法更新')
    return
  }
  
  console.log('[TaskLogModal] 处理日志事件:', event.type, event.executionId)
  
  switch (event.type) {
    case 'execution_started':
    case 'output_update':
      // 更新输出内容
      log.value.output = event.fullOutput
      log.value.status = event.status as TaskExecution['status']
      
      console.log('[TaskLogModal] 更新输出，长度:', event.fullOutput.length)
      
      // 自动滚动到底部
      setTimeout(() => {
        if (logContentRef.value) {
          logContentRef.value.scrollTop = logContentRef.value.scrollHeight
        }
      }, 50)
      break
      
    case 'execution_completed':
      // 执行完成，更新最终状态
      log.value.output = event.fullOutput
      log.value.status = event.status as TaskExecution['status']
      log.value.duration = event.duration || 0
      log.value.endTime = event.timestamp
      isRealTimeMode.value = false
      
      console.log('[TaskLogModal] 任务执行完成:', event.status)
      break
  }
}

// 生命周期管理
onMounted(() => {
  // 监听WebSocket日志事件
  on('log_event', handleLogEvent)
})

onUnmounted(() => {
  // 清理WebSocket事件监听
  off('log_event', handleLogEvent)
})
</script>

<style lang="less" scoped>
.task-log-modal {
  :deep(.ant-modal-body) {
    padding: 0;
  }
}

.log-container {
  display: flex;
  flex-direction: column;
  height: 600px;
  
  .log-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px 24px;
    border-bottom: 1px solid #f0f0f0;
    background: #fafafa;
    
    .log-info {
      display: flex;
      align-items: center;
      gap: 16px;
      
      .label {
        color: #666;
        font-size: 13px;
      }
      
      .value {
        color: #333;
        font-size: 13px;
      }
    }
    
    .actions {
      display: flex;
      gap: 8px;
      
      .anticon {
        font-size: 16px;
      }
    }
  }
  
  .log-content {
    flex: 1;
    overflow: auto;
    padding: 16px 24px;
    background: #1e1e1e;
    
    .output-text {
      margin: 0;
      padding: 0;
      color: #d4d4d4;
      font-family: Consolas, Monaco, 'Courier New', monospace;
      font-size: 13px;
      line-height: 1.5;
      white-space: pre-wrap;
      word-break: break-all;
    }
    
    .no-output {
      color: #666;
      text-align: center;
      padding: 32px 0;
    }
  }
}

:deep(.ant-spin-container) {
  height: 100%;
}
</style> 